/* 1videoConference -- An open source video conferencing platform.
* Copyright (C) 2007 - 2008, Adiance Technologies Pvt. Ltd.
*
* Hardik Sanghvi <hardik.sanghvi @adiance.com>
*
* See http://www.1videoconference.org for more information about
* the 1videoConference project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, forums and mailing lists
* for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
********************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.Reflection;
using Adiance.VMukti.DAL;
using System.Windows;
using System.IO;
using InterfaceFiles;
using NetPeerService;

namespace Adiance.VMukti.BAL
{
    public class CliLoginInfo
    {
        NetPeerService.NetPeerServer LoginInfoServer = null;

        NetPeerService.NetPeerClient npcLoginInfo = null;
        object objLoginInfo = new CsvcLoginInfo();
        IsvcLoginInfoChannel LoginInfoChannel;

        System.Threading.Thread servClient;
        /// <summary>
        /// Server class declaration
        /// 
        /// </summary>
        string meetingID = "";
        string serviceAddress;
        Assembly a;
        Assembly b = Assembly.GetAssembly(typeof(CliLoginInfo));
        public static int counter = 1;
        List<ServiceHost> myServices = new List<ServiceHost>();
        public static List<object[]> serverControlslist = new List<object[]>();
        public static List<object[]> objlist = new List<object[]>();
        public static List<string> HostedMeetings = new List<string>();
        bool IssvcInterfaceFilesCreated = false;
        string ServerIPAddr = "";

        public CliLoginInfo(string MainServiceURI)
        {
            ServerIPAddr = MainServiceURI.Replace("net.tcp://", "").Split(':')[0];

            //LoginInfoServer = new NetPeerService.NetPeerServer(MainServiceURI);
            //LoginInfoServer.AddEndPoint(MainServiceURI);
            //LoginInfoServer.OpenServer();

            servClient = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(RegClient));
            try
            {
                servClient.Start(MainServiceURI);                
            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "LoginInfo--:--CliLoginInfo.cs--:--CliLoginInfo(parameterised)--:--");
                Adiance.VMukti.BAL.clsUtility.LogException = exp;
                //System.Windows.MessageBox.Show("Presentation--:--CliPresentation.cs--:--CliPresentation2(parameterised)--:--" + exp.Message);
            }
        }

        void RegClient(object MainServiceURI)
        {
            try
            {
                ((CsvcLoginInfo)objLoginInfo).EntsvcJoin += new CsvcLoginInfo.DelsvcJoin(CliLoginInfo_EntsvcJoin);
                ((CsvcLoginInfo)objLoginInfo).EntsvcGetDatabaseIP += new CsvcLoginInfo.DelsvcGetDatabaseIP(CliLoginInfo_EntsvcGetDatabaseIP);
                ((CsvcLoginInfo)objLoginInfo).EntsvcSetDatabaseIP += new CsvcLoginInfo.DelsvcSetDatabaseIP(CliLoginInfo_EntsvcSetDatabaseIP);
                ((CsvcLoginInfo)objLoginInfo).EntsvcSetMID += new CsvcLoginInfo.DelsvcSetMID(CliLoginInfo_EntsvcSetMID);
                ((CsvcLoginInfo)objLoginInfo).EntsvcUnSetMID += new CsvcLoginInfo.DelsvcUnSetMID(CliLoginInfo_EntsvcUnSetMID);
                ((CsvcLoginInfo)objLoginInfo).EntsvcSetVar += new CsvcLoginInfo.DelsvcSetVar(CliLoginInfo_EntsvcSetVar);
                ((CsvcLoginInfo)objLoginInfo).EntsvcUnJoin += new CsvcLoginInfo.DelsvcUnJoin(CliLoginInfo_EntsvcUnJoin);
            
                npcLoginInfo = new NetPeerService.NetPeerClient();
                LoginInfoChannel = (IsvcLoginInfoChannel)npcLoginInfo.OpenClient<IsvcLoginInfoChannel>(MainServiceURI.ToString(), "LoginInfoMesh", ref objLoginInfo);
                LoginInfoChannel.svcJoin("Server");
            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "Adiance.VMukti.VCServer--:--CliUriInfo.cs--:--RegClient()--:--");
                Adiance.VMukti.BAL.clsUtility.LogException = exp;
                //MessageBox.Show(exp.Message);
            }
        }

        void CliLoginInfo_EntsvcSetVar()
        {
            
        }

        void CliLoginInfo_EntsvcJoin(string UName)
        {
            
        }

        void CliLoginInfo_EntsvcGetDatabaseIP(string UName, string mid)
        {
            string[] DBCredentials = new string[3];
            DBCredentials[0] = UserInfo.ConSitePath.Replace("http://", "").Split('/')[0];
            DBCredentials[1] = UserInfo.strDBUser;
            DBCredentials[2] = UserInfo.strDBPass;
            setdatabasecred(DBCredentials, UName, mid);
            //LoginInfoChannel.svcSetDatabaseIP(DBCredentials, UName, mid);
        }

        void CliLoginInfo_EntsvcSetDatabaseIP(string[] DatabaseIP, string UName, string mid)
        {

        }

        void CliLoginInfo_EntsvcSetMID(string mid)
        {
            lock (this)
            {
                try
                {
                    bool hostM = false;
                    meetingID = mid;
                    if (!IssvcInterfaceFilesCreated)
                    {
                        svcInterfaceFiles s = new svcInterfaceFiles();
                        IssvcInterfaceFilesCreated = true;
                    }

                    int i = 0;
                    for (i = 0; i < HostedMeetings.Count; i++)
                    {
                        if (HostedMeetings[i] == mid)
                        {
                            break;
                        }
                    }
                    if (i == HostedMeetings.Count)
                    {
                        hostM = hostmethod();                        
                        HostedMeetings.Add(mid);
                        LoginInfoChannel.svcSetVar();
                    }
                    else
                    {
                        hostM = true;
                        LoginInfoChannel.svcSetVar();
                    }
                    //return hostM;
                }
                catch (Exception exp)
                {
                    exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--SetMID()--:----:--");
                    Adiance.VMukti.BAL.clsUtility.LogException = exp;
                    //System.Windows.MessageBox.Show("VCServer--:--svcLoginInfo.cs--:--SetMID()--:--" + exp.Message);
                    //return false;
                }
            }
        }

        void CliLoginInfo_EntsvcUnSetMID(string mid)
        {
            int i = 0;
            try
            {
                for (i = 0; i < HostedMeetings.Count; i++)
                {
                    if (HostedMeetings[i] == mid)
                    {
                        break;
                    }
                }

                if (i < HostedMeetings.Count)
                {
                    HostedMeetings.RemoveAt(i);
                    i = 0;
                    while (serverControlslist.Count > 0 && i < serverControlslist.Count)
                    {
                        if (serverControlslist[i][1].ToString() == mid)
                        {
                            ((NetPeerServer)serverControlslist[i][0]).CloseServer();
                            for (int j = 0; j < UserServices.ServiceURI.Count; j++)
                            {
                                if (((UriList)UserServices.ServiceURI[j]).Uriname == serverControlslist[i][2].ToString())
                                {
                                    UserServices.ServiceURI.RemoveAt(j);
                                    break;
                                }
                            }
                            serverControlslist.RemoveAt(i);
                        }
                        else
                        {
                            i++;
                        }
                    }

                    i = 0;
                    while (objlist.Count > 0 && i < objlist.Count)
                    {
                        if (objlist[i][1].ToString() == mid)
                        {
                            MethodInfo mi = ((Type)objlist[i][2]).GetMethod("CloseService");
                            mi.Invoke(objlist[i][0], null);
                            objlist.RemoveAt(i);
                        }
                        else
                        {
                            i++;
                        }
                    }
                    //return true;
                }
                else
                {
                    //return false;
                }
            }
            catch (Exception exp)
            {
                exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--UnSetMID()--:----:--");
                Adiance.VMukti.BAL.clsUtility.LogException = exp;
                //System.Windows.MessageBox.Show("Host Method Main:" + exp.InnerException.ToString());
                //return false;
            }
        }

        void CliLoginInfo_EntsvcUnJoin(string UName)
        {

        }
        
        public bool hostmethod()
        {
            lock (this)
            {
                try
                {
                    string[] FileList = Directory.GetFiles(b.Location.Replace("Adiance.VMukti.BAL.dll", @"Business Layer"), "*.dll", SearchOption.AllDirectories);
                    for (int j = 0; j < FileList.Length; j++)
                    {
                        a = Assembly.LoadFrom(FileList[j].ToString());
                        AssemblyName[] an = a.GetReferencedAssemblies();

                        #region reference
                        try
                        {
                            for (int alcount = 0; alcount < svcInterfaceFiles.alAllFiles.Count; alcount++)
                            {
                                string strsplit = svcInterfaceFiles.alAllFiles[alcount].ToString();
                                string[] strold = strsplit.Split('\\');
                                string strnew = strold[strold.Length - 1].Substring(0, strold[strold.Length - 1].Length - 4);

                                for (int asscount = 0; asscount < an.Length; asscount++)
                                {
                                    if (an[asscount].Name == strnew)
                                    {
                                        Assembly assbal = System.AppDomain.CurrentDomain.Load(System.Reflection.Assembly.LoadFrom(svcInterfaceFiles.alAllFiles[alcount].ToString()).GetName());
                                        AssemblyName[] anbal = assbal.GetReferencedAssemblies();
                                        for (int andal = 0; andal < svcInterfaceFiles.alAllFiles.Count; andal++)
                                        {
                                            string strsplitdal = svcInterfaceFiles.alAllFiles[andal].ToString();
                                            string[] strolddal = strsplitdal.Split('\\');
                                            string strnewdal = strolddal[strolddal.Length - 1].Substring(0, strolddal[strolddal.Length - 1].Length - 4);

                                            for (int asscountdal = 0; asscountdal < anbal.Length; asscountdal++)
                                            {
                                                if (anbal[asscountdal].Name == strnewdal)
                                                {
                                                    Assembly assdal = System.AppDomain.CurrentDomain.Load(System.Reflection.Assembly.LoadFrom(svcInterfaceFiles.alAllFiles[andal].ToString()).GetName());
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception exp)
                        {
                            exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--hostmethod()1--:----:--");
                            Adiance.VMukti.BAL.clsUtility.LogException = exp;
                            //System.Windows.MessageBox.Show("Loading Reference Files: " + exp.Message);
                            return false;
                        }
                        #endregion

                        Type[] alltypes = a.GetTypes();

                        for (int xmlCount = 0; xmlCount < UserServices.MyServices.Count; xmlCount++)
                        {
                            if (FileList[j].Replace(FileList[j].Split('\\')[FileList[j].Split('\\').Length - 1], "") == UserServices.MyServices[xmlCount].XmlFileName.Replace(UserServices.MyServices[xmlCount].XmlFileName.Split('\\')[UserServices.MyServices[xmlCount].XmlFileName.Split('\\').Length - 1], ""))
                            {
                                for (int ctlServices = 0; ctlServices < UserServices.MyServices[xmlCount].ServiceName.Count; ctlServices++)
                                {
                                    Type t1 = null;
                                    Type t2 = null;
                                    Type t3 = null;


                                    NetPeerServer serverControls;

                                    NetTcpBinding binding = new NetTcpBinding();

                                    #region NetPeerTcpBinding

                                    if (UserServices.MyServices[xmlCount].BindingType[ctlServices].ToLower() == "netpeertcpbinding")
                                    {
                                        for (int k = 0; k < alltypes.Length; k++)
                                        {
                                            if (alltypes[k].IsClass)
                                            {
                                                if (UserServices.MyServices[xmlCount].ClassName.Count > 0)
                                                {
                                                    if (alltypes[k].Name == UserServices.MyServices[xmlCount].ClassName[ctlServices].ToString())
                                                    {
                                                        t3 = a.GetType(alltypes[k].FullName);
                                                    }
                                                }
                                            }
                                            if (t3 != null)
                                            {
                                                break;
                                            }
                                        }

                                        #region UriFormation

                                        if (meetingID != null && meetingID != "")
                                        {
                                            serviceAddress = "net.tcp://" + UserInfo.strMachIP + ":2500/" + meetingID + "/" + counter;
                                            UserServices.ServiceURI.Add(new UriList(serviceAddress, UserServices.MyServices[xmlCount].ControlName, UserServices.MyServices[xmlCount].ServiceName[ctlServices].ToString(), meetingID));
                                            counter++;

                                            serverControls = new NetPeerServer(serviceAddress);
                                            serverControls.AddEndPoint(serviceAddress);
                                            serverControls.OpenServer();

                                            //System.Windows.MessageBox.Show("Server hosted for " + UserServices.MyServices[xmlCount].ControlName);

                                            serverControlslist.Add(new object[] { serverControls, meetingID, serviceAddress });

                                            //System.Windows.MessageBox.Show("server hosted for " + t3.ToString());
                                        }
                                        else
                                        {
                                            System.Windows.MessageBox.Show("Could not start the service as Meeting id is not provided");
                                        }

                                        #endregion

                                        if (t3 != null)
                                        {
                                            #region ServiceHosting + ObjectCreation

                                            object[] args = new object[2] { serviceAddress, meetingID };

                                            try
                                            {
                                                if (UserServices.MyServices[xmlCount].Parameters[ctlServices].ToString() == "true")
                                                {
                                                    try
                                                    {
                                                        //objlist.Add(new object());
                                                        //objlist[objlist.Count - 1] = Activator.CreateInstance(t3, args);

                                                        objlist.Add(new object[] { Activator.CreateInstance(t3, args), meetingID, t3 });
                                                    }
                                                    catch (Exception exp)
                                                    {
                                                        exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--hostmethod()2--:----:--");
                                                        Adiance.VMukti.BAL.clsUtility.LogException = exp;
                                                        System.Windows.MessageBox.Show("Hosting the methods" + exp.Message);
                                                    }
                                                }
                                                else
                                                {
                                                    //objlist.Add(new object());
                                                    //objlist[objlist.Count - 1] = Activator.CreateInstance(t3);
                                                    objlist.Add(new object[] { Activator.CreateInstance(t3), meetingID, t3 });
                                                }

                                            }
                                            catch (Exception exp)
                                            {
                                                exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--hostmethod()3--:----:--");
                                                Adiance.VMukti.BAL.clsUtility.LogException = exp;
                                                System.Windows.MessageBox.Show("NetPeerTcpBinding:" + exp.Message);
                                            }
                                            #endregion
                                        }
                                    }
                                    #endregion

                                    #region NetTcpBinding

                                    if (UserServices.MyServices[xmlCount].BindingType[ctlServices].ToLower() == "nettcpbinding")
                                    {
                                        for (int k = 0; k < alltypes.Length; k++)
                                        {
                                            if (alltypes[k].IsInterface)
                                            {
                                                if (UserServices.MyServices[xmlCount].ServerInterface.Count > 0)
                                                {
                                                    if (alltypes[k].Name == UserServices.MyServices[xmlCount].ServerInterface[ctlServices].ToString())
                                                    {
                                                        t1 = a.GetType(alltypes[k].FullName);
                                                    }
                                                }
                                            }
                                            if (alltypes[k].IsClass)
                                            {
                                                if (UserServices.MyServices[xmlCount].ServerClass.Count > 0)
                                                {
                                                    if (alltypes[k].Name == UserServices.MyServices[xmlCount].ServerClass[ctlServices].ToString())
                                                    {
                                                        t2 = a.GetType(alltypes[k].FullName);
                                                    }
                                                }
                                            }
                                            if (t1 != null && t2 != null)
                                            {
                                                break;
                                            }
                                        }

                                        if (t1 != null && t2 != null)
                                        {
                                            #region UriFormation

                                            if (meetingID != null && meetingID != "")
                                            {
                                                serviceAddress = "net.tcp://" + UserInfo.strMachIP + ":2500/" + meetingID + "/" + counter;
                                                UserServices.ServiceURI.Add(new UriList(serviceAddress, UserServices.MyServices[xmlCount].ControlName, UserServices.MyServices[xmlCount].ServiceName[ctlServices].ToString(), meetingID));
                                                counter++;
                                            }

                                            else
                                            {
                                                System.Windows.MessageBox.Show("Could not start the service as Meeting id is not provided");
                                            }

                                            #endregion

                                            try
                                            {
                                                if (UserServices.MyServices[xmlCount].ServiceBinding[ctlServices].ToLower() == "buffered")
                                                {
                                                    binding.TransferMode = TransferMode.Buffered;
                                                    binding.PortSharingEnabled = true;
                                                }
                                                else if (UserServices.MyServices[xmlCount].ServiceBinding[ctlServices].ToLower() == "streamed")
                                                {
                                                    binding.TransferMode = TransferMode.Streamed;
                                                    binding.PortSharingEnabled = true;
                                                    binding.MaxBufferPoolSize = long.MaxValue;
                                                    binding.MaxBufferSize = int.MaxValue;
                                                    binding.MaxConnections = 10;
                                                    binding.MaxReceivedMessageSize = long.MaxValue;
                                                    binding.ReceiveTimeout = new TimeSpan(0, 5, 0);
                                                    binding.ListenBacklog = int.MaxValue;
                                                    binding.ReliableSession.Ordered = true;
                                                }

                                                UserServices.ServiceThreads.Add(new ThreadedServiceHoster(serviceAddress, binding, t2, t1));
                                                //System.Windows.MessageBox.Show("hostmethod for " + t2.ToString());
                                            }
                                            catch (Exception exp)
                                            {
                                                exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--hostmethod()--:----:--");
                                                Adiance.VMukti.BAL.clsUtility.LogException = exp;
                                                //System.Windows.MessageBox.Show("Host Method Inner:" + exp.Message);
                                            }
                                        }

                                    }
                                    #endregion
                                }
                            }
                        }
                    }
                }
                catch (Exception exp)
                {
                    exp.Data.Add("My Key", "Adiance.VMukti.BAL--:--svcLoginInfo.cs--:--hostmethod()5--:----:--");
                    Adiance.VMukti.BAL.clsUtility.LogException = exp;
                    //System.Windows.MessageBox.Show("Host Method Main:" + exp.InnerException.ToString());
                    return false;
                }
                return true;
            }
        }

        public void setdatabasecred(string[] dbcred, string uname, string mid)
        {
            LoginInfoChannel.svcSetDatabaseIP(dbcred, uname, mid);
        }
    }
}
